package api

import (
	"strconv"

	"github.com/gin-gonic/gin"

	categoryApp "BookStack/internal/application/category"
	"BookStack/internal/interfaces/middleware"
	"BookStack/internal/interfaces/presenter"
)

// CategoryHandler 分类处理器
type CategoryHandler struct {
	categoryService categoryApp.Service
	response        presenter.ResponseFormatter
}

// NewCategoryHandler 创建分类处理器
func NewCategoryHandler(categoryService categoryApp.Service) *CategoryHandler {
	return &CategoryHandler{
		categoryService: categoryService,
		response:        presenter.NewResponseFormatter(),
	}
}

// RegisterRoutes 注册路由
func (h *CategoryHandler) RegisterRoutes(r *gin.RouterGroup) {
	// 公开接口
	public := r.Group("/category")
	{
		public.GET("/list", h.ListCategories)
		public.GET("", h.GetCategory) // 支持通过id或slug参数获取分类
		public.GET("/tree", h.GetCategoryTree)
	}

	// 需要认证的API
	auth := r.Group("/category")
	auth.Use(middleware.JWTAuth()) // 认证中间件
	{
		// 这里可以添加需要用户认证的API
	}

	// 管理员接口
	admin := r.Group("/admin/category")
	admin.Use(middleware.JWTAuth(), middleware.AdminAuth()) // 管理员权限认证中间件
	{
		admin.GET("/list", h.AdminListCategories) // 管理员获取分类列表
		admin.POST("", h.CreateCategory)
		admin.PUT("/:id", h.UpdateCategory)
		admin.DELETE("/:id", h.DeleteCategory)
		admin.PUT("/:id/order", h.UpdateCategoryOrder)
	}
}

// ListCategories 获取分类列表
// @Summary 获取分类列表
// @Description 获取所有可见的分类列表
// @Tags 分类
// @Accept json
// @Produce json
// @Param page query int false "页码，默认为1"
// @Param page_size query int false "每页数量，默认为20，最大100"
// @Param type query int false "分类类型（1：文章分类，2：书籍分类）"
// @Success 200 {object} response.Response{data=category.CategoryListResponse}
// @Router /api/v1/category/list [get]
func (h *CategoryHandler) ListCategories(c *gin.Context) {
	var params categoryApp.CategoryListQueryParams
	if err := c.ShouldBindQuery(&params); err != nil {
		c.Error(err)
		return
	}

	// 设置默认值
	if params.Page <= 0 {
		params.Page = 1
	}
	if params.PageSize <= 0 {
		params.PageSize = 10
	} else if params.PageSize > 100 {
		params.PageSize = 100
	}

	// 移除对status参数的处理，应用层已固定只返回已发布的分类

	// 如果未指定类型，设置为-1表示查询所有类型
	if params.Type == 0 {
		params.Type = -1
	}

	result, err := h.categoryService.ListCategories(c.Request.Context(), &params)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, result)
}

// GetCategory 获取分类详情（支持通过id或slug）
// @Summary 获取分类详情
// @Description 获取指定ID或Slug的分类详情
// @Tags 分类
// @Accept json
// @Produce json
// @Param id query string false "分类ID"
// @Param slug query string false "分类别名"
// @Success 200 {object} response.Response{data=category.CategoryResponse}
// @Router /api/v1/category [get]
func (h *CategoryHandler) GetCategory(c *gin.Context) {
	id := c.Query("id")
	slug := c.Query("slug")

	if id != "" {
		// 通过ID获取
		categoryID, err := strconv.ParseUint(id, 10, 32)
		if err != nil {
			c.Error(categoryApp.ValidationError("id", "无效的分类ID"))
			return
		}

		result, err := h.categoryService.GetCategory(c.Request.Context(), uint(categoryID))
		if err != nil {
			c.Error(err)
			return
		}

		h.response.Success(c, result)
		return
	} else if slug != "" {
		// 通过Slug获取
		result, err := h.categoryService.GetCategory(c.Request.Context(), uint(0)) // TODO: 需要实现通过slug获取分类的方法
		if err != nil {
			c.Error(err)
			return
		}

		h.response.Success(c, result)
		return
	}

	// 参数不足
	c.Error(categoryApp.ValidationError("params", "请提供id或slug参数"))
}

// CreateCategory 创建分类
// @Summary 创建分类
// @Description 创建新的分类
// @Tags 分类
// @Accept json
// @Produce json
// @Param category body category.CreateCategoryRequest true "分类信息"
// @Success 201 {object} response.Response{data=category.CategoryResponse}
// @Router /api/v1/admin/category [post]
func (h *CategoryHandler) CreateCategory(c *gin.Context) {
	var req categoryApp.CreateCategoryRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	// 获取当前用户ID
	userID, err := middleware.GetUserID(c)
	if err != nil {
		c.Error(err)
		return
	}

	result, err := h.categoryService.CreateCategory(c.Request.Context(), &req, userID)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Created(c, result)
}

// UpdateCategory 更新分类
// @Summary 更新分类
// @Description 更新现有分类
// @Tags 分类
// @Accept json
// @Produce json
// @Param id path int true "分类ID"
// @Param category body category.UpdateCategoryRequest true "分类信息"
// @Success 200 {object} response.Response{data=category.CategoryResponse}
// @Router /api/v1/admin/category/{id} [put]
func (h *CategoryHandler) UpdateCategory(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(categoryApp.ValidationError("id", "无效的分类ID"))
		return
	}

	var req categoryApp.UpdateCategoryRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	// 获取当前用户ID
	userID, err := middleware.GetUserID(c)
	if err != nil {
		c.Error(err)
		return
	}

	result, err := h.categoryService.UpdateCategory(c.Request.Context(), uint(id), &req, userID)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, result)
}

// DeleteCategory 删除分类
// @Summary 删除分类
// @Description 删除分类
// @Tags 分类
// @Accept json
// @Produce json
// @Param id path int true "分类ID"
// @Success 200 {object} response.Response
// @Router /api/v1/admin/category/{id} [delete]
func (h *CategoryHandler) DeleteCategory(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(categoryApp.ValidationError("id", "无效的分类ID"))
		return
	}

	// 获取当前用户ID
	userID, err := middleware.GetUserID(c)
	if err != nil {
		c.Error(err)
		return
	}

	if err := h.categoryService.DeleteCategory(c.Request.Context(), uint(id), userID); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// GetCategoryTree 获取分类树
// @Summary 获取分类树
// @Description 获取分类的树形结构
// @Tags 分类
// @Accept json
// @Produce json
// @Param type query int true "分类类型（1：文章分类，2：书籍分类）"
// @Success 200 {object} response.Response{data=[]category.CategoryResponse}
// @Router /api/v1/category/tree [get]
func (h *CategoryHandler) GetCategoryTree(c *gin.Context) {
	categoryType, err := strconv.Atoi(c.Query("type"))
	if err != nil {
		c.Error(categoryApp.ValidationError("type", "无效的分类类型"))
		return
	}

	result, err := h.categoryService.GetCategoryTree(c.Request.Context(), categoryType)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, result)
}

// UpdateCategoryOrder 更新分类排序
// @Summary 更新分类排序
// @Description 更新分类的排序顺序
// @Tags 分类
// @Accept json
// @Produce json
// @Param id path int true "分类ID"
// @Param order body category.UpdateCategoryOrderRequest true "排序信息"
// @Success 200 {object} response.Response
// @Router /api/v1/admin/category/{id}/order [put]
func (h *CategoryHandler) UpdateCategoryOrder(c *gin.Context) {
	id, err := strconv.ParseUint(c.Param("id"), 10, 32)
	if err != nil {
		c.Error(categoryApp.ValidationError("id", "无效的分类ID"))
		return
	}

	var req categoryApp.UpdateCategoryOrderRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.Error(err)
		return
	}

	// 获取当前用户ID
	userID, err := middleware.GetUserID(c)
	if err != nil {
		c.Error(err)
		return
	}

	orders := map[uint]int{
		uint(id): req.Order,
	}

	if err := h.categoryService.UpdateCategoryOrder(c.Request.Context(), orders, userID); err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, nil)
}

// AdminListCategories 管理员获取分类列表
// @Summary 管理员获取分类列表
// @Description 管理员获取所有分类列表，包括未发布的分类
// @Tags 分类
// @Accept json
// @Produce json
// @Param page query int false "页码，默认为1"
// @Param page_size query int false "每页数量，默认为20，最大100"
// @Param type query int false "分类类型（1：文章分类，2：书籍分类）"
// @Param status query int false "分类状态（0：未发布，1：已发布）"
// @Success 200 {object} response.Response{data=category.CategoryListResponse}
// @Router /api/v1/admin/category/list [get]
func (h *CategoryHandler) AdminListCategories(c *gin.Context) {
	var params categoryApp.CategoryListQueryParams
	if err := c.ShouldBindQuery(&params); err != nil {
		c.Error(err)
		return
	}

	// 设置默认值
	if params.Page <= 0 {
		params.Page = 1
	}
	if params.PageSize <= 0 {
		params.PageSize = 20
	} else if params.PageSize > 100 {
		params.PageSize = 100
	}

	// 如果未指定类型，设置为-1表示查询所有类型
	if params.Type == 0 {
		params.Type = -1
	}

	result, err := h.categoryService.AdminListCategories(c.Request.Context(), &params)
	if err != nil {
		c.Error(err)
		return
	}

	h.response.Success(c, result)
}
